package com.mcp.converter.domain.rule.compatibility.function;

import com.mcp.converter.domain.checker.IncompatibilityDetail;
import com.mcp.converter.shared.response.sql.SQLElement;
import com.mcp.converter.domain.rule.compatibility.AbstractFunctionRule;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 编码解码函数兼容性规则
 * OceanBase在编码解码函数方面与Oracle存在显著差异
 * @author zengxiong
 */
public class EncodingDecodingFunctionRule extends AbstractFunctionRule {

    private static final String RULE_ID = "FN002";
    private static final String RULE_NAME = "编码解码函数不兼容";
    private static final String RULE_DESCRIPTION = "OceanBase不支持或实现方式不同的编码解码函数";

    private static final Set<String> ENCODING_FUNCTIONS = new HashSet<>(Arrays.asList(
        "EMPTY_BLOB", "EMPTY_CLOB", "ENCRYPT_RAW",
        "SHA1", "SHA256", "SHA384", "SHA512"
    ));

    public EncodingDecodingFunctionRule() {
        super(RULE_ID, RULE_NAME, RULE_DESCRIPTION);
        
        StringBuilder reasonBuilder = new StringBuilder("OceanBase在以下编码解码函数方面与Oracle不兼容：\n");
        StringBuilder impactBuilder = new StringBuilder("可能导致：\n");
        StringBuilder suggestionBuilder = new StringBuilder("建议：\n");
        
        // 大对象处理函数
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "EMPTY_BLOB", "BLOB空值处理机制不同",
            "大对象操作失败", "使用应用层初始化BLOB");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "EMPTY_CLOB", "CLOB空值处理机制不同",
            "大对象操作失败", "使用应用层初始化CLOB");
        
        // 加密函数
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "ENCRYPT_RAW", "加密算法实现不兼容",
            "数据加密失败", "使用应用层加密方案");
        
        // 哈希函数
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SHA1", "SHA-1哈希算法不支持",
            "数据完整性校验失败", "使用标准SQL哈希函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SHA256", "SHA-256哈希算法不支持",
            "数据完整性校验失败", "使用标准SQL哈希函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SHA384", "SHA-384哈希算法不支持",
            "数据完整性校验失败", "使用标准SQL哈希函数");
        addFunctionInfo(reasonBuilder, impactBuilder, suggestionBuilder,
            "SHA512", "SHA-512哈希算法不支持",
            "数据完整性校验失败", "使用标准SQL哈希函数");
        
        setIncompatibilityDetail(
            reasonBuilder.toString(),
            impactBuilder.toString(),
            suggestionBuilder.toString(),
            IncompatibilityDetail.Severity.HIGH
        );
    }
    
    private void addFunctionInfo(StringBuilder reasonBuilder, StringBuilder impactBuilder, StringBuilder suggestionBuilder,
                                 String functionName, String reason, String impact, String suggestion) {
        reasonBuilder.append(" - ").append(functionName).append(": ").append(reason).append("\n");
        impactBuilder.append(" - ").append(functionName).append(": ").append(impact).append("\n");
        suggestionBuilder.append(" - ").append(functionName).append(": ").append(suggestion).append("\n");
    }

    @Override
    public boolean matches(Object target) {
        if (target instanceof SQLElement) {
            SQLElement element = (SQLElement) target;
            if (isFunctionElement(element)) {
                String functionName = element.getName().toUpperCase();
                return ENCODING_FUNCTIONS.contains(functionName);
            }
        }
        return false;
    }
    
    @Override
    public Set<String> getIncompatibleFunctions() {
        return new HashSet<>(ENCODING_FUNCTIONS);
    }
}